<?php
App::uses('Model', 'Model');

class AppModel extends Model {

	var $useDbConfig = 'default';
	
	var $tablePrefix;
	
	var $defaultDbConfig = 'default';
	var $masterDbConfig = 'master';
	
	private $_extschema = array();
	
	public $recursive = -1;
// 	public $actsAs = array('Containable');
	
	private $_modelinfo = array();
	
	private $version_flag = true; // 是否记录版本信息，用于在业务逻辑中设置不记录版本信息
	
	public function __construct($id = false, $table = null, $ds = null) {
		$this->setDataSource($this->defaultDbConfig);		
		parent::__construct($id, $table, $ds);
		if($this->name=='Ajax' || $this->name=='Ajaxis'){
			return false;
		}
		$this->getModelInfo();

		if(!empty($this->_modelinfo['modeltype'])){
			if($this->_modelinfo['modeltype'] == 'tree'){
				if(!isset($this->actsAs['Tree'])){
					$this->Behaviors->attach('Tree',array('left'=>'left','right'=>'right'));
					$this->actsAs['Tree'] = array('left'=>'left','right'=>'right');
				}
			}
			/**
			 * 在模型表信息中，配置使用的behavior，动态启用行为
			 */
// 			if(!empty($GLOBALS['model_behaviors']['*'])){
// 				foreach($GLOBALS['model_behaviors']['*'] as $behavior => $config){
// 					$this->Behaviors->load($behavior, $config);
// 				}
// 			}
			if(!empty($GLOBALS['model_behaviors'][$this->name])){
				foreach($GLOBALS['model_behaviors'][$this->name] as $behavior => $config){
					$this->Behaviors->load($behavior, $config);
				}
			}
		}
		
		if(!empty($this->_modelinfo['related_model'])){
			$ralated_models = json_decode($this->_modelinfo['related_model'],true);
			if(is_array($ralated_models)){
				foreach($ralated_models as $hastype => $assoc){
						
					foreach($assoc as $r_modelname => $variables){					    
						if(ModelExists($r_modelname)){
						    $this->{$hastype}[$r_modelname] = array_merge( array(
						        'className'     => $r_modelname,
						        //'foreignKey'    => $variables['foreignKey'],
						        'order'    => $r_modelname.'.id ASC',
						        'limit'        => 100,
						        'dependent'=> true,
						        'unique'=> true,
						        'exclusive'=> false,
						    ),$variables);
						}
					}
				}
			}
			
		}
		
		if($this->_modelinfo['localetype']=='1' && $this->table && substr($this->name,-4)!='I18n') { //开启多语言1对1
		    try{
    		    if($i18n_model = loadModelObject($this->name.'I18n')) {
    				$i18n_fields = $i18n_model->schema();
    				$fields = array();
    				foreach($i18n_fields as $field_name => $field){
    					if(in_array($field['type'],array('string','text','content','char','varchar','mediumtext')) && $field_name != 'locale'){
    						$fields[] = $field_name;
    					}
    				}
    				$this->getExtSchema();
    				$ext_fields = array_keys($this->_extschema);
    				$config_fields = array_intersect ($fields,$ext_fields);
    				$this->Behaviors->load('MultiTranslate', $config_fields);
    				$GLOBALS['model_behaviors'][$this->name]['MultiTranslate'] = $config_fields;
    				
    				$this->recursive = 1;
    			};
		    }
		    catch(MissingTableException $e){
		        CakeLog::error($e->getMessage());
		    }
		    catch(Exception $e){
		        CakeLog::error($e->getMessage());
		    }
			
		}
	}
	/**
	 *  加载数据表结构
	 */
	public function getExtSchema(){
		//echo $local = Configure::read('Site.language');
		if(!$this->table){
			return array();
		}
		if(empty($this->_extschema)){
			$cachekey = 'extschema_'.$this->name;
			$this->_extschema = Cache::read($cachekey,'_cake_model_'); 
			if ($this->_extschema === false) {
				$this->_extschema=array();
				if($this->name=='I18nfield'){
					$I18nObj = $this;
				}
				else{
					$I18nObj =  loadModelObject('I18nfield');
				}
				$I18nObj->recursive = -1;
		    	$tempextschema = $I18nObj->find('all',array(
					'conditions'=>array('model'=>$this->name,'deleted'=>0), //'locale'=> $locale,'savetodb'=>1
			  		'order' => array('sort desc'),
			  		)
			  	);
		    	
			  	foreach($tempextschema as $value){
			  		$this->_extschema[$value['I18nfield']['name']] = $value['I18nfield'];
			  	}
			  	Cache::write($cachekey,$this->_extschema,'_cake_model_'); 
			}
		}
		return $this->_extschema;
	}
	
	public function getItemById($id,$recursive=-1,$force = false){
	    $cache_key = md5('item_'.$this->name.'_'.$id.'_'.$recursive);
	    $item = Cache::read($cache_key);
	    if( $force || $item === false) {
	        $item = $this->find('first',array(
				'conditions' => array(
				    'id' => $id,
				),
	            'recursive' => $recursive,
	        ));
	        Cache::write($cache_key, $item);
	    }
	    return $item;
	}
	public function getItemByField($field,$field_val,$recursive=-1){
	    $cache_key = md5('item_'.$this->name.'_'.$field.'_'.$field_val.'_'.$recursive);
	    $item = Cache::read($cache_key);
	    if($item === false) {
	        $item = $this->find('first',array(
	            'conditions' => array(
	                $field => $field_val,
	            ),
	            'recursive' => $recursive,
	        ));
	        Cache::write($cache_key, $item);
	    }
	    return $item;
	}

	public function isContentModel(){
		$this->getModelInfo();
		if($this->_modelinfo['cate_id']==1){
			return true;
		}
		return false;
	}
	/**
	 * 加载模块结构
	 */
	public function getModelInfo()
	{
		$cachekey = 'extend_info_'.$this->name;
		$this->_modelinfo = Cache::read($cachekey,'_cake_model_');
		if ($this->_modelinfo === false) {
			$this->_modelinfo=array();
			if($this->name=='Modelextend'){
				$extobj = $this;
			}
			else{
				$extobj =  loadModelObject('Modelextend');
			}
			$extobj->recursive = -1;
			$tempextschema = $extobj->find('first',array('conditions'=>array(
					'name'=> $this->name,  // Inflector::classify()
			)));
			$this->_modelinfo = $tempextschema['Modelextend'];
			 
			Cache::write($cachekey,$this->_modelinfo,'_cake_model_');
		}
		
		return $this->_modelinfo;
	}
	

	
	public function escape_string($value){
		return $this->getDataSource()->value($value);
	}
	
	public function beforeSave($options = array())
	{
	     $this->setDataSource($this->masterDbConfig);
	     return true;
	}
	
	// query方法支持主从
	public function query($sql) {
		$params = func_get_args();
		$this->beforeSave();
		$db =& ConnectionManager::getDataSource($this->useDbConfig);
		$result = call_user_func_array(array(&$db, 'query'), $params);
		//$result = parent::query($params);
		$this->afterSave();
		return $result;
	}
	
	public function setVersionFlag($flag = false) {
	    $this->version_flag = $flag ;
	}
	 
	public function afterSave($created=false)
	{
	    if( in_array( $this->name , array('WxMsg','UserRole') ) && $this->version_flag ) {
	        $version_flag = true;
	        if($this->name == 'WxMsg') {
	            $userinfo = CakeSession::read('Auth.User');
	            
	            if( !is_array($userinfo['role_id']) ) {
	                $userinfo['role_id'] = array_filter(explode(',',$userinfo['role_id']));
	            }
	            if( !empty($userinfo['Role']) ) {
	                foreach($userinfo['Role'] as $role) {
	                    if( !in_array($role['id'],$userinfo['role_id']) ){
	                        $userinfo['role_id'][] = $role['id'];
	                    }
	                }
	            }
	            if( $userinfo['id'] && count($userinfo['role_id']) > 1 ) {
	                // 对微信文章付费用户，有超过一个用户组的才允许记录历史版本。否则直接返回
	            }
	            else{
	                $version_flag = false; // 免费用户不记录版本号，将最近的50次保存内容存为草稿，便于付费后的内容恢复。
	                if($created == false) {
		                $draft = loadModelObject('Draft');
		                $draft->create();
		                $vd = array(
	                		'model' => $this->name,
	                		'data_id' => $this->id,
	                		'creator' => $this->data[$this->name]['creator'],
	                		'name' => $this->data[$this->name]['name'],
	                		'content' => $this->data[$this->name]['content'],
		                );
		                $draft->save($vd);
		                
		                $drafts = $draft->find('list',array(
		                		'conditions' => array( 'creator' => $this->data[$this->name]['creator'],'model' => $this->name ),
		                		'order' => 'id desc',
		                		'limit' => 50,
		                		'page' => 2,
		                )); //大于50条的第二页数据删除。
		                if( !empty($drafts) ){
		                	$ids = array_keys($drafts);
		                	$draft->deleteAll(array('id'=>$ids),false,false);
		                }
	                }
	            }
	        }
	        
	    	if( $version_flag && $this->id){
	    		$vesion_c = loadModelObject('VersionControl');
	    		$vesion_c->primaryKey = 'version_id';
	    		$vesion_c->create();
	    		$vd = array(
	    				'data_id' => $this->id,
	    				'model' => $this->name,
	    				'content' => json_encode($this->data),
	    				'user_id' => $this->data[$this->name]['user_id'] ? $this->data[$this->name]['user_id'] : $this->data[$this->name]['creator'],
	    				'url' => Router::url(),
	    		);
	    		$vesion_c->save($vd);
	    	}
	    }
	    
	    $this->setDataSource($this->defaultDbConfig);
		return true;
	}
	 
	public function beforeDelete($cascade = true)
	{
	    $this->setDataSource($this->masterDbConfig); 
		return true;
	}
	 
	public function afterDelete()
	{
	    $this->setDataSource($this->defaultDbConfig); 
		return true;
	}
	
	/**
	 * 仅修改单条数据时，触发Behaviors的beforeSave和afterSave 
	 * @see Model::updateAll()
	 */
	public function updateAll($fields, $conditions = true) {
		
		if(empty($conditions)){ //update的条件.没有设置条件时，禁止update
			return false;
		}
		$this->beforeSave();
		// 调用beforeFind，根据beforeFind处理查看的条件。 主要用于拆分表时，根据条件找到对应的分表
		$event = new CakeEvent('Model.beforeFind', $this, array(array('conditions'=>$conditions)));
		list($event->break, $event->breakOn, $event->modParams) = array(true, array(false, null), 0);
		$this->getEventManager()->dispatch($event);
		
		
        $output = parent::updateAll($fields, $conditions);
        //$args = func_get_args();
        //$output = call_user_func_array(array('parent', 'updateAll'), $args);
        $created = false; // $created表示新建数据
        if ($output) {
        	if( isset($conditions[$this->name.'.'.$this->primaryKey]) || isset($conditions[$this->primaryKey]) ) {
	            $options = array();
	            $this->Behaviors->trigger('afterSave', array(&$this, $created, $options));
        	}
            
            // tree行为afterSave中，调用了updateAll修改左右节点。
            // 保存后再触发afterSave，注意$created = false;否则会陷入死循环
            $this->_clearCache();
            //$this->id = false;
        }
	    $this->afterSave($created);
	    return $output;
	}
	
	public function deleteAll($conditions,$cascade = true, $callbacks = true){
		// 调用beforeFind，根据beforeFind处理查看的条件。 主要用于拆分表时，根据条件找到对应的分表
		$event = new CakeEvent('Model.beforeFind', $this, array(array('conditions'=>$conditions)));
		list($event->break, $event->breakOn, $event->modParams) = array(true, array(false, null), 0);
		$this->getEventManager()->dispatch($event);
		
		if( !$callbacks ){
			$this->beforeDelete($cascade);
		}
		
		// 将$callbacks默认设置成true，调用时，逐条删除，每条删除时都会触发beforeDelete与afterDelete
		// 为false时，一次性删除。手动在前后触发beforeDelete与afterDelete
        $output = parent::deleteAll($conditions,$cascade,$callbacks);
        
        if( !$callbacks ){
        	$this->afterDelete($cascade);
        }
        
        return $output;
	}
	
	public function saveAll($data = null, $options = array())
	{
		$this->beforeSave();
		$return = parent::saveAll($data, $options);
		$this->afterSave();
		return $return;
	}
}
?>
